package rpg.writer.app.player;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicLong;

import rpg.client.Instruction;
import rpg.client.model.Actor;
import rpg.client.model.GameEvent;
import rpg.engine.client.GameEngineFacade;

public class Communication implements Runnable {
    private static void debug(Object o) {
        // System.out.println("Communication: " + o);
    }

    private final List<GameEvent> events = new Vector<GameEvent>();

    private final GameEngineFacade engine;
    private final PlayerJPanel player;
    private final Actor character;

    private final Instruction pass;

    private volatile boolean stopRequested = false;

    private final AtomicLong lastInstruction = new AtomicLong(0);

    public Communication(Actor pc, GameEngineFacade facade, PlayerJPanel gui) {
        super();
        character = pc;
        engine = facade;
        player = gui;
        pass = Instruction.pass(character.getId());
        events.addAll(engine.addPlayer(character));
    }

    public void requestStop() {
        stopRequested = true;
    }

    @Override
    public void run() {
        for (;;) {
            if (stopRequested) {
                break;
            }

            Instruction ins = null;

            while (!events.isEmpty()) {
                GameEvent ge = events.remove(0);
                ins = player.render(ge);
                if (ins != null) {
                    break;
                }
            }

            if (ins != null) {
                sendInstruction(ins);
            }
            else {
                long nowIs = System.currentTimeMillis();
                long delta = nowIs - lastInstruction.get();
                if (delta > 1000) {
                    sendInstruction(pass);
                }
            }
        }
    }

    public void sendInstruction(Instruction instruction) {
        lastInstruction.set(System.currentTimeMillis());

        debug(instruction);
        List<GameEvent> newEvents = engine.instruction(instruction);
        events.addAll(newEvents);

        List<Instruction> newInstructions = engine.getPossibleInstructions(character.getId());
        player.updateInstruction(newInstructions);
    }
}
